var Player = function() {
	this.bounds = {
		h:50,
		w:50
	};

	this.coords = {
		x:-40,
		y:160,
		dx: -1,
		dy: 1 
	};

	// Définition des variables relatives au saut
	/** The maximum height of the jump
	@type Number
	*/
	this.jumpHeight = this.bounds.h;
	/** The constant or half PI
	@type Number
	*/
	this.halfPI = Math.PI / 2;
	/** The amount of time to spend in the air when jumping
	@type Number
	*/
	this.jumpHangTime = 0.5;
	/** The speed to progress alone the sine wave that defines
	the jumping arc
	@type Number
	*/
	this.jumpSinWaveSpeed = this.halfPI / this.jumpHangTime;
	/** The current position on the sine wave that defines the jump arc
	@type Number
	*/
	this.jumpSinWavePos = 0;
	/** The rate to fall at
	@type Number
	*/
	this.fallMultiplyer = 1.5;

	// Etats du joueur
	this.grounded = true;
	this.run = false

	this.state = 0;
	this.speed = 2;

	this.sprites = playerSprite.idle;

	/** Array of projectiles throught by player
	@type Array of object
	*/
	this.tProjectiles = [];
	this.lastShoot = 0;
	this.timeBetweenShoot = 18;

	// Lifes of the player
	this.life = 3;


	this.update = function(dt) {
		this.input();

		// if the player is jumping or falling, move along the sine wave
		if (!this.grounded) {
			this.jumpAndFall(dt);
		}
	}

	this.render = function(ctx) {
		animateSprites(this);
		// Save current context
		ctx.save();
		// Scale according to player's direction
		ctx.scale(-this.coords.dx, 1);
		// Render sprites in the appropriate direction
		renderSprites(this);

		// Restore context
		ctx.restore();
	}

	this.input = function() {
		var top = 'idle';
		var bottom = 'idle'; 
		this.run = false;

		if ( getKey('up').state && this.grounded) {
			this.grounded = false;
			this.jumpSinWavePos = 0;
		}

		if ( getKey('down').state ) {
			this.moveDown();
		}

		if ( getKey('right').state ) {
			if(this.moveRight() === true) {
				bottom = 'run';
				this.run = true;
			}
		}

		if ( getKey('left').state ) {
			if(this.moveLeft() === true) {
				bottom = 'run';
				this.run = true;
			}
		}

		if ( getKey('space').state ) {
			if(this.shoot() === true) {
				top = 'shoot';
			}
		}
		else
			this.lastShoot++;

		this.sprites = playerSprite.instance(top, bottom);

	}

	// Input methods
	this.jumpAndFall = function(dt) {
		// the last position on the sine wave
		var lastHeight = this.jumpSinWavePos;
		// the new position on the sine wave
		this.jumpSinWavePos += this.jumpSinWaveSpeed * dt;
		// we have fallen off the bottom of the sine wave, so continue falling
		// at a predetermined speed
		if (this.jumpSinWavePos >= Math.PI)
			this.coords.y += this.jumpHeight / this.jumpHangTime * this.fallMultiplyer * dt;
		// otherwise move along the sine wave
		else
			this.coords.y -= (Math.sin(this.jumpSinWavePos) - Math.sin(lastHeight)) * this.jumpHeight;

		if (this.coords.y > map.bounds.groundLevel ) {
			this.coords.y = map.bounds.groundLevel;
			this.grounded = true;
			this.jumpSinWavePos = 0;
		}
	}

	this.moveDown = function() {
		log('Crounch', 'moveDown() - Player.js');
	}

	this.moveRight = function() {
		this.coords.dx = -1;
		return this.moveHorizontaly();
	}

	this.moveLeft = function() {
		this.coords.dx = 1;
		return this.moveHorizontaly();
	}

	this.shoot = function() {
		if (this.lastShoot == 0) {
			var projectile = new Bullet();
			// this.tProjectiles[0] = projectile.init(this); // Debug
			BulletManager.entities.push(projectile.init(this));
		}

		this.lastShoot++;

		if (this.lastShoot > this.timeBetweenShoot)
			this.lastShoot = 0;

		return true;
	}

	this.moveHorizontaly = function() {
		var x = this.coords.x + this.speed * this.coords.dx;
		if(this.isInBounds(map.bounds) === true) {
			var x_abs = x < 0 ? -x : x;
			if ((x_abs <= map.bounds.w/2 - this.bounds.w) || map.isStep === true) { 
				this.coords.x = x;
			} else {
				// Update enemies from player (coods.x & dx)
				for(var i = 0, c = EnemyManager.entities.length; i < c; i++) {
					var enemy = EnemyManager.entities[i];
					enemy.coords.x -= this.coords.dx * this.speed;
				}
			}

		}

		return true;
	}

	this.isInBounds = function(bounds) {
		var x = this.bounds.w/2 + this.coords.x + this.speed * this.coords.dx;
		if(x > 0 || Math.abs(x) >= bounds.w - this.bounds.w) {
			return false;
		}

		return true;
	}

	this.kill = function() {
		if( --this.life > 0 )
			this.respawn();
		else
			log('Game Over');
	}

	this.respawn = function() {
		log('Respawn - Lifes : '+this.life);
	}
};